<template>
    <div style="width: 600px;margin: 0px auto;">
        <el-row>
            <el-col :span="12">
                <el-input v-model="roleName" style="width: 240px;margin: 5px auto" placeholder="请输入角色名称">
                    <template #append>
                        <el-button :icon="Search" @click="showRoleName" />
                    </template>
                </el-input>
                <el-tree ref="roleTreeRef" style="max-width: 600px" :data="roleTreeList" show-checkbox
                    default-expand-all node-key="id" highlight-current :props="defaultProps" getCheckedKeys
                    setCheckedKeys :expand-on-click-node="false" @node-click="handleNodeClick"
                    :filter-node-method="filterNodeForRole" />
            </el-col>
            <el-col :span="12">
                <el-input v-model="menuName" style="width: 240px;margin: 5px auto" placeholder="请输入权限名称">
                    <template #append>
                        <el-button :icon="Search" @click="showMenuName" />
                    </template>
                </el-input>
                <el-tree ref="treeRef" style="max-width: 600px" :data="menuTreeList" show-checkbox default-expand-all
                    node-key="value" highlight-current :props="defaultProps" getCheckedKeys
                    :expand-on-click-node="false" :filter-node-method="filterNode" />
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="24">
                <p style="float: right;">
                    <el-button @click="saveSelRole()">
                        确定保存
                    </el-button>
                </p>
            </el-col>
        </el-row>
    </div>
</template>


<script setup lang="ts">
import { ref, onMounted, inject, watch } from 'vue'
import { ElMessage, ElTree } from 'element-plus'
import type { TreeKey } from 'element-plus/es/components/tree/src/tree.type.mjs';
import { Search } from '@element-plus/icons-vue'

import http from '@/http'

// 树形结构属性
const defaultProps = {
    children: 'children',
    label: 'label',
    value: 'id'
}
interface Tree {
    id: number
    label: string
    parentId: number
    children?: Tree[]
}

// 角色树形数据
const roleTreeList = ref<Tree[]>([])
const roleAll = ref<Tree[]>([])
const getRoleTreeList = () => {
    http.get("/api/Menu/GetRoleTree").then(res => {
        roleAll.value = res.data;
        roleTreeList.value = ([{
            id: 0,
            label: '角色',
            parentId: 0,
            children: res.data
        }]);
    })
}

// 选中的权限菜单列表
const roleId = ref(0)
const selPressionList = ref<TreeKey[]>([])
const roleTreeRef = ref<InstanceType<typeof ElTree>>()
const treeRef = ref<InstanceType<typeof ElTree>>()
// 角色名称切换权限点击事件
const handleNodeClick = (data: Tree) => {
    roleId.value = data.id;
    getMenuInfoByRoleId(roleId.value);
}

// 保存角色权限关系
const saveSelRole = () => {
    selPressionList.value = treeRef.value!.getCheckedKeys(false);
    if (selPressionList.value.length == 0) {
        ElMessage({
            type: 'warning',
            message: '至少选择一项权限',
            duration: 1000
        });
        return;
    }
    http.post("/api/Menu/PressionInsert?roleId=" + roleId.value, selPressionList.value).then(res => {
        if (res.data > 0) {
            ElMessage({
                type: 'success',
                message: '保存成功',
                duration: 1000
            });
        }
        else {
            ElMessage({
                type: 'error',
                message: '保存失败',
                duration: 1000
            });
        }
    })
}

// 菜单树形数据
const menuTreeList = ref<Tree[]>([])
const menuAll = ref<Tree[]>([])
const getMenuTreeList = () => {
    http.get("/api/Menu/GetMenuListDTO").then(res => {
        menuTreeList.value = res.data;
        menuAll.value = res.data;
    })
}

// 根据角色Id获取菜单权限信息
const getMenuInfoByRoleId = (roleId: number) => {
    http.get("/api/Menu/GetMenuIdsByRoleId?roleId=" + roleId).then(res => {
        selPressionList.value = res.data;
        treeRef.value!.setCheckedKeys(selPressionList.value, true);
    });
}

// 角色树形输入框
const roleName = ref("")
const selRoleTree = ref<TreeKey[]>([])
const showRoleName = () => {
    selRoleTree.value = [];
    roleAll.value.forEach(ele => {
        if (roleName.value == ele.label) {
            selRoleTree.value.push(ele.id);
        };
    });
    roleTreeRef.value!.setCheckedKeys(selRoleTree.value, true);
    treeRef.value!.setCheckedKeys([], true);
    let rId = Number(roleTreeRef.value!.getCheckedKeys(true)) ?? 0;
    if (rId != 0) getMenuInfoByRoleId(rId);
}

// 菜单树形输入框
const menuName = ref("")
const showMenuName = () => {
    http.get("/api/Menu/GetMenuListDTOByMenuName", {
        params: {
            menuName: menuName.value
        }
    }).then(res => {
        menuTreeList.value = res.data;
    })
}

// 树形过滤器
interface Trees {
    [key: string]: any
}
// 菜单名称
// =================================================
// 侦听器
watch(menuName, (val) => {
    treeRef.value!.filter(val)
})

// 过滤事件
const filterNode = (value: string, data: Trees) => {
    if (!value) return true
    return data.label.includes(value)
}

// 角色名称
// =================================================
// 侦听器
watch(roleName, (val) => {
    roleTreeRef.value!.filter(val)
})

// 过滤事件
const filterNodeForRole = (value: string, data: Trees) => {
    if (!value) return true
    return data.label.includes(value)
}

onMounted(() => {
    getRoleTreeList();
    getMenuTreeList();
})
</script>

<style scoped></style>